package com.ruoyi.rsikManage.task;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.GenericMethodsService;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.rsikManage.domain.MonitorPoint;
import com.ruoyi.rsikManage.domain.TUnitConfig;
import com.ruoyi.rsikManage.domain.VideoDiagnosisResult;
import com.ruoyi.rsikManage.domain.vo.MonitorPointDiagnosisResultVo;
import com.ruoyi.rsikManage.mapper.VideoDiagnosisMapper;
import com.ruoyi.rsikManage.service.ITUnitConfigService;
import com.ruoyi.rsikManage.service.JyService;
import com.ruoyi.rsikManage.service.VideoDiagnosisService;
import lombok.Getter;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Getter
@Setter
public class VideoDiagnosisScheduler implements SchedulingConfigurer {
    @Value("${scheduler.videoDiagnosisUpdateCron}")
    private String initialVideoDiagnosisUpdateCron;
    @Value("${scheduler.videoDiagnosisUpdateCron}")
    private String videoDiagnosisUpdateCron;
    @Value("${jy.switch}")
    private boolean JY_SWITCH;

    @Value("${system.permissionVersion}")
    private String SYSTEM_PermissionVersion;

    private boolean isLastReceiveCornErr;
    @Autowired
    VideoDiagnosisService videoDiagnosisService;
    @Autowired
    VideoDiagnosisMapper videoDiagnosisMapper;
    @Autowired
    JyService jyService;

    @Autowired
    ITUnitConfigService tUnitConfigService;

    @Autowired
    TokenService tokenService;

    @Autowired
    private GenericMethodsService genericMethodsService;

    // 获取 Logger 实例
    private static final Logger logger = LoggerFactory.getLogger(VideoDiagnosisScheduler.class);
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(() -> {
            if (JY_SWITCH) {
                recordVideoDiagnosisResultForUnitCodes();
            }
        }, triggerContext -> {
            // 使用CronTrigger触发器，动态修改cron表达式来操作循环规则
            CronTrigger cronTrigger;
            if (isLastReceiveCornErr) {
                cronTrigger = new CronTrigger(initialVideoDiagnosisUpdateCron);
            }else {
                try {
                    cronTrigger = new CronTrigger(videoDiagnosisUpdateCron);
                }catch (IllegalArgumentException e) {
                    System.out.println("上次接收的videoDiagnosisUpdateCron:\""+ videoDiagnosisUpdateCron + "\" 格式错误，videoDiagnosisUpdateCron 更新为初始值======");
                    cronTrigger = new CronTrigger(initialVideoDiagnosisUpdateCron);
                    isLastReceiveCornErr = true;
                }
            }
            return cronTrigger.nextExecutionTime(triggerContext);
        });
    }

    public void recordVideoDiagnosisResult() {
        HashMap param = new HashMap();
        param.put("page_num", 1);
        param.put("page_size", 99999);
        // 查询所有最新的视频质量诊断结果
        String lastVideoDiagnosisResult = jyService.getLastVideoDiagnosisResult(param);
        List<VideoDiagnosisResult> list = toDiagnosisResultListObject(lastVideoDiagnosisResult);
        videoDiagnosisService.insertVideoDiagnosisResultList(list);
        // 查询最新视频质量诊断结果中诊断为异常的结果
        param.put("diagnosis_result", "fail");
        String abnormalVideoDiagnosisResult = jyService.getLastVideoDiagnosisResult(param);
        List<VideoDiagnosisResult> abnormalVideoDiagnosisResultList = toDiagnosisResultListObject(abnormalVideoDiagnosisResult);
        videoDiagnosisService.recordAbnormalDiagnosticResultList(abnormalVideoDiagnosisResultList);
    }

    public void recordVideoDiagnosisResultForUnitCodes() {
        HashMap param = new HashMap();
        param.put("page_num", 1);
        param.put("page_size", 99999);
        // 查询所有最新的视频质量诊断结果

        //判断是否为集团模式 如果是则从各个一体极获取信息
        if(SYSTEM_PermissionVersion.equals("1")){
            Map<Long, SysDept> deptMap = genericMethodsService.getDeptMap();
            // 将 Map 转换为 List
            List<SysDept> deptList = deptMap.values().stream().collect(Collectors.toList());
            List<Long> unitCodes = new ArrayList<>();
            for (SysDept dept:deptList){
                unitCodes.add(dept.getUnitCode());
                System.out.println(dept.getUnitCode());
            }

            TUnitConfig tUnitConfig = new TUnitConfig();
            tUnitConfig.setUnitCodes(unitCodes);
            List<TUnitConfig> tUnitConfigs = tUnitConfigService.selectTUnitConfigList(tUnitConfig);

            for (TUnitConfig Unit: tUnitConfigs){
                try {
                    // 获取最新的视频诊断结果
                String lastVideoDiagnosisResult = jyService.getLastVideoDiagnosisResultForUnitCodes(Unit,param);
                List<VideoDiagnosisResult> list = toDiagnosisResultListObjectForUnitCodes(lastVideoDiagnosisResult,Unit.getUnitCode());
                videoDiagnosisService.insertVideoDiagnosisResultListForUnitCodes(list);
                // 查询最新视频质量诊断结果中诊断为异常的结果
                param.put("diagnosis_result", "fail");
                String abnormalVideoDiagnosisResult = jyService.getLastVideoDiagnosisResultForUnitCodes(Unit,param);
                List<VideoDiagnosisResult> abnormalVideoDiagnosisResultList = toDiagnosisResultListObjectForUnitCodes(abnormalVideoDiagnosisResult,Unit.getUnitCode());
                videoDiagnosisService.recordAbnormalDiagnosticResultListForUnitCodes(abnormalVideoDiagnosisResultList);
                } catch (Exception e) {
                    // 记录异常信息，可以使用日志框架如 SLF4J
                    logger.error("Error processing unit code {}: {}", Unit.getUnitCode(), e.getMessage(), e);
                    // 继续处理下一个单元
                }
            }
        }

    }

    List<VideoDiagnosisResult> toDiagnosisResultListObject(String diagnosisResultListJsonStr) {
        List<VideoDiagnosisResult> res = new ArrayList<>();
        JSONArray diagnosisResultJsonArray = JSONObject.parseObject(diagnosisResultListJsonStr).getJSONObject("data").getJSONArray("data");
        for (int i = 0; i < diagnosisResultJsonArray.size(); i++) {
            JSONObject j = diagnosisResultJsonArray.getJSONObject(i);
            //诊断结果对象
            VideoDiagnosisResult diagnosisResult = new VideoDiagnosisResult();
            //初始化诊断结果对象
            diagnosisResult.setChannelCode(j.getString("ape_id"))
                    .setDiagnosisTime(j.getDate("diagnosis_time"))
                    .setResult(j.getInteger("result"))
                    .setDiagnosisResultReason(j.getString("diagnosis_result_reason"))
                    .setColorCast(j.getInteger("color_cast"))
                    .setContrastRatio(j.getInteger("contrast_ratio"))
                    .setCrossStriation(j.getInteger("cross_striation"))
                    .setDefinition(j.getInteger("definition"))
                    .setFreeze(j.getInteger("freeze"))
                    .setHighLuminance(j.getInteger("high_luminance"))
                    .setJitter(j.getInteger("jitter"))
                    .setLoss(j.getInteger("loss"))
                    .setLowLuminance(j.getInteger("low_luminance"))
                    .setNoise(j.getInteger("noise"))
                    .setOcclusion(j.getInteger("occlusion"))
                    .setRollingStripe(j.getInteger("rolling_stripe"))
                    .setSceneChange(j.getInteger("scene_change"))
                    .setStripe(j.getInteger("stripe"))
                    .setTransverseWave(j.getInteger("transverse_wave"));
            res.add(diagnosisResult);

        }
        return res;
    }

    List<VideoDiagnosisResult> toDiagnosisResultListObjectForUnitCodes(String diagnosisResultListJsonStr,Long unitCode) {
        List<VideoDiagnosisResult> res = new ArrayList<>();
        JSONArray diagnosisResultJsonArray = JSONObject.parseObject(diagnosisResultListJsonStr).getJSONObject("data").getJSONArray("data");
        for (int i = 0; i < diagnosisResultJsonArray.size(); i++) {
            JSONObject j = diagnosisResultJsonArray.getJSONObject(i);
            //诊断结果对象
            VideoDiagnosisResult diagnosisResult = new VideoDiagnosisResult();
            //初始化诊断结果对象
            diagnosisResult
                    .setUnitCode(unitCode)
                    .setChannelCode(j.getString("ape_id"))
                    .setDiagnosisTime(j.getDate("diagnosis_time"))
                    .setResult(j.getInteger("result"))
                    .setDiagnosisResultReason(j.getString("diagnosis_result_reason"))
                    .setColorCast(j.getInteger("color_cast"))
                    .setContrastRatio(j.getInteger("contrast_ratio"))
                    .setCrossStriation(j.getInteger("cross_striation"))
                    .setDefinition(j.getInteger("definition"))
                    .setFreeze(j.getInteger("freeze"))
                    .setHighLuminance(j.getInteger("high_luminance"))
                    .setJitter(j.getInteger("jitter"))
                    .setLoss(j.getInteger("loss"))
                    .setLowLuminance(j.getInteger("low_luminance"))
                    .setNoise(j.getInteger("noise"))
                    .setOcclusion(j.getInteger("occlusion"))
                    .setRollingStripe(j.getInteger("rolling_stripe"))
                    .setSceneChange(j.getInteger("scene_change"))
                    .setStripe(j.getInteger("stripe"))
                    .setTransverseWave(j.getInteger("transverse_wave"));
            res.add(diagnosisResult);

        }
        return res;
    }
    @Scheduled(cron = "0 0 0 * * ?")
    public void deleteVideoDiagnosisResultHistory() {
        videoDiagnosisService.deleteVideoDiagnosisResultHistory();
    }
}

